package com.xy.biz.uc.domain.converter;

import com.xy.biz.uc.domain.bo.ResourceBO;
import com.xy.biz.uc.domain.bo.RoleBO;
import com.xy.biz.uc.domain.bo.UserBO;
import com.xy.biz.uc.domain.bo.UserGroupBO;
import com.xy.biz.uc.domain.dto.UserDTO;
import com.xy.biz.uc.domain.po.UserPO;
import com.xy.biz.uc.domain.query.UserQuery;
import com.xy.biz.uc.domain.req.ListUserRequest;
import com.xy.biz.uc.domain.req.LockUserRequest;
import com.xy.biz.uc.domain.req.SaveUserRequest;
import com.xy.biz.uc.domain.req.SearchUserRequest;
import com.xy.biz.uc.domain.resp.CurrentUserResponse;
import com.xy.biz.uc.domain.resp.GetUserGroupResponse;
import com.xy.biz.uc.domain.resp.GetUserNameResponse;
import com.xy.lang.domain.LongIdCodeName;
import com.xy.tool.util.BeanUtilsEx;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 *
 *
 * @author zsp
 * @date 2020-8-19
 */
public class UserConverter {

    public static UserPO toPO(UserBO source) {
        return BeanUtilsEx.copyProperties(source, () -> new UserPO(), true);
    }

    public static List<UserPO> toPO(Collection<UserBO> source) {
        return BeanUtilsEx.copyPropertiesForNewList(source, () -> new UserPO(), true);
    }

    public static UserBO fromPO(UserPO source) {
        return BeanUtilsEx.copyProperties(source, () -> new UserBO());
    }

    public static List<UserBO> fromPO(Collection<UserPO> source) {
        return BeanUtilsEx.copyPropertiesForNewList(source, () -> new UserBO());
    }

    public static UserBO toBO(SaveUserRequest source) {
        return BeanUtilsEx.copyProperties(source, () -> new UserBO(), true);
    }

    public static UserBO toBO(LockUserRequest source) {
        return BeanUtilsEx.copyProperties(source, () -> new UserBO(), true);
    }

    public static List<UserBO> toBO(Collection<SaveUserRequest> source) {
        return BeanUtilsEx.copyPropertiesForNewList(source, () -> new UserBO(), true);
    }

    public static UserDTO toDTO(UserBO source) {
        UserDTO target = null;
        if (source != null) {
            target = new UserDTO();
            BeanUtilsEx.copyProperties(source, target);
            buildDTO(source, target);
        }
        return target;
    }

    public static List<UserDTO> toDTO(Collection<UserBO> source) {
        return BeanUtilsEx.copyPropertiesForNewList(source, () -> new UserDTO(), (s, t) -> buildDTO(s, t));
    }

    private static void buildDTO(UserBO source, UserDTO target) {
        if (source == null) {
            return;
        }
        LongIdCodeName longIdCodeName;
        Set<RoleBO> roleBOSet = source.getRoleBOSet();
        if (!CollectionUtils.isEmpty(roleBOSet)) {
            List<LongIdCodeName> roleList = new ArrayList<>();
            for (RoleBO roleBO : roleBOSet) {
                longIdCodeName = new LongIdCodeName();
                longIdCodeName.setId(roleBO.getRoleId());
                longIdCodeName.setCode(roleBO.getRoleCode());
                longIdCodeName.setName(roleBO.getName());
                roleList.add(longIdCodeName);
            }
            target.setRoleList(roleList);
        }
        UserGroupBO userGroupBO = source.getUserGroupBO();
        if (userGroupBO != null) {
            longIdCodeName = new LongIdCodeName();
            longIdCodeName.setId(userGroupBO.getUserGroupId());
            longIdCodeName.setName(userGroupBO.getUserGroupName());
            longIdCodeName.setAbbr(userGroupBO.getUserGroupAbbr());
            target.setUserGroup(longIdCodeName);
        }
    }

    public static CurrentUserResponse toCurrentUserResponse(UserBO source) {
        //复制属性
        CurrentUserResponse target = BeanUtilsEx.copyProperties(source, CurrentUserResponse::new);
        //复制角色
        if (!CollectionUtils.isEmpty(source.getRoleBOSet())) {
            target.setRoles(source.getRoleBOSet().stream().map(RoleBO::getRoleCode).collect(Collectors.toList()));
        }
        //复制部门
        if (!Objects.isNull(source.getUserGroupBO())) {
            target.setUserGroupBO(UserGroupConverter.toResponse(source.getUserGroupBO()));
        }
        //复制资源菜单
        if (!CollectionUtils.isEmpty(source.getResourceBOSet())) {
            List<CurrentUserResponse.Menu> menus = ResourceBO.visitTree(source.getResourceBOSet(),
                    current -> BeanUtilsEx.copyProperties(current, () -> new CurrentUserResponse.Menu()),
                    (current, children) -> current.setChildren(BeanUtilsEx.copyPropertiesForNewList(children, () -> new CurrentUserResponse.Menu())));
            target.setMenusMap(menus.stream().collect(Collectors.groupingBy(CurrentUserResponse.Menu::getModule)));
        }
        return target;
    }

    public static UserQuery toQuery(ListUserRequest source) {
        if (null == source) {
            return null;
        }
        UserQuery target = new UserQuery(source.getPageIndex(), source.getPageSize());
        BeanUtilsEx.copyProperties(source, target);
        return target;
    }

    public static UserQuery toQuery(SearchUserRequest source) {
        if (null == source) {
            return null;
        }
        UserQuery target = new UserQuery(source.getPageIndex(), source.getPageSize());
        BeanUtilsEx.copyProperties(source, target);
        return target;
    }


    public static GetUserNameResponse toUserNameResponse(UserBO source) {
        if (null == source) {
            return null;
        }
        return BeanUtilsEx.copyProperties(source, () -> new GetUserNameResponse());
    }

}
